#include <stdio.h>
#include <sys/time.h>
#include <sys/times.h>
#include <atmi.h>
#include <fml32.h>
#include <Usysfl32.h>
#include <tpadm.h>

#include <errno.h>
#include <sys/procfs.h>
#include <fcntl.h>

#define	MAXSRV	600

#define	STRDBG(x, y)	printf("%s:	%s\n", x, y)
#define	LNGDBG(x, y)	printf("%s:	%ld\n", x, y)

struct usrvinfo {
	char	name[32]	[MAXSRV];
	long	srvid		[MAXSRV];
	long	pid		[MAXSRV];
};
typedef struct usrvinfo USRVINFO;

FBFR32 	*sendbuf, *rcvbuf;
char	*ta_status;

int tpgetsvrseqno( void )
{
	USRVINFO	srv, *psrv;
	long		occurs;
	long		svrid_min;
	int		i;
	pid_t		pid_c;
	char		exec_file_name	[1024];

	if((sendbuf = (FBFR32 *)tpalloc("FML32", NULL, 1024)) == NULL) {
		printf("tpalloc error : %s\n",tpstrerror(tperrno));
		exit(1);
	}
	if((rcvbuf = (FBFR32 *)tpalloc("FML32", NULL, sizeof(USRVINFO))) == NULL) {
		printf("tpalloc error : %s\n",tpstrerror(tperrno));
		tpfree((char *)sendbuf);
		exit(1);
	}

	pid_c = getpid();
#if 1
	get_exec_filename(exec_file_name, pid_c);
#endif
#if 1
printf("----------------PID:%ld, svr_name:%s\n", pid_c, exec_file_name);
#endif
	psrv = &srv;
	memset(psrv->name, 0x00, sizeof(psrv->name[0]));
	strcpy(psrv->name, exec_file_name);
	if(get_srvinfo(&svrid_min, &occurs, psrv) != 0) {
		printf("get_srvinfo error\n");
		tpfree((char *)sendbuf);
		tpfree((char *)rcvbuf);
		exit(1);
	}
	tpfree((char *)sendbuf);
	tpfree((char *)rcvbuf);
	for ( i = 0; i < occurs; i++ ) {

		if( psrv->pid[i] == pid_c) {
			
#if 1
			printf( " psrv->srvid[i]:%d - min_svrid:%d = %d\n",
psrv->srvid[i], svrid_min,
psrv->srvid[i] - svrid_min );
#endif
			return( psrv->srvid[i] - svrid_min );
		}
	}

	return(-1);
}

int get_srvinfo(long *svrid_min, long *occurs, USRVINFO *pusrv)
{
	long    i, len;
	long	ta_error;
	long tmp_svrid=0;

	Finit32(sendbuf, Fsizeof32(sendbuf));
   	Finit32(rcvbuf, Fsizeof32(rcvbuf));
	Fchg32(sendbuf, TA_CLASS, 	0, "T_SERVER", 0);
 	Fchg32(sendbuf, TA_OPERATION, 	0, "GET", 0);
 	Fchg32(sendbuf, TA_SERVERNAME, 	0, pusrv->name[0], 0);

	if(tpcall(".TMIB", (char *)sendbuf, 0, (char **)&rcvbuf, &len, TPNOTRAN|TPNOCHANGE|TPSIGRSTRT|TPNOTIME) == -1) {
		printf("tpcall failed: %s\n", tpstrerror(tperrno));
		if( tperrno == TPESVCFAIL ) {
			Fget32(rcvbuf, TA_ERROR, 0, (char *)&ta_error, 0);
			printf("get_srvinfo failure: %ld\n", ta_error);
		}
		return(-1);
	}

	Fget32(rcvbuf, TA_OCCURS, 0, (char *)occurs, 0);
/*
		printf("---->get_srvinfo OCCURS[%d]\n", *occurs);
*/

	for(i =0; i < *occurs; i++) {
		Fget32(rcvbuf, TA_SRVID, 	i, (char *)&pusrv->srvid[i], 0);
		Fget32(rcvbuf, TA_PID, 		i, (char *)&pusrv->pid[i], 0);

		if( !tmp_svrid ) 
			tmp_svrid = pusrv->srvid[i];
		if(pusrv->srvid[i] && (tmp_svrid > pusrv->srvid[i]) )
			tmp_svrid = pusrv->srvid[i];
#if 0
		printf("---->get_srvinfo[%d]: %d, %d\n", i, pusrv->srvid[i],
pusrv->pid[i]);
		printf("----> tmp_svrid:[%ld] .vs. pusrv->srvid[i]: [%ld]\n",
			tmp_svrid, pusrv->srvid[i]);
#endif
/*
		LNGDBG(">get_srvinfo", pusrv->srvid[i]);
		LNGDBG(">get_srvinfo", pusrv->pid[i]);
*/
	}
	*svrid_min = tmp_svrid;
	return(0);
}

int get_exec_filename(char *exec_file_name, pid_t nPID)
{
	int 	nPathLen = 0;
	char 	szCmdLinePath[0xFF];
	int 	fp;
	struct psinfo pinfo;	

	char szCmdLine[0xFF];

	nPathLen = sprintf(szCmdLinePath, "/proc/%d/psinfo", nPID);
	szCmdLinePath[nPathLen] = 0;
#if 0
	printf("my pid is %d, path [%s]\n", nPID, szCmdLinePath);
#endif
	if( (fp = open(szCmdLinePath, O_RDONLY)) == NULL )
	{
		printf("fail to open %s, %s\n", szCmdLinePath, strerror(errno));
		return 0;
	}
	memset( &pinfo, 0x00, sizeof(pinfo));
	if( read( fp, (void *)&pinfo, sizeof(pinfo)) < 0 )
	{
		printf("my command line path %s\n", szCmdLinePath);
		return 0;
	}
	strcpy( exec_file_name, pinfo.pr_fname);
#if 0
	memset(szCmdLine, 0x00, 0xFF);
	if( fgets(szCmdLine, 0xFF, fpCmdLine) )
	{
		const char *pszBinName = NULL;
		printf("my command line is %s\n", szCmdLine);

		if ( (pszBinName = (const char *)strrchr(szCmdLine, '/')) != NULL )
			printf("my binary name is %s\n", pszBinName+1);
	}
#endif

	close(fp);
	return 0;
}

